﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ESRI.ArcGIS.Geodatabase;
using System.Collections;
using System.Text.RegularExpressions;
using ESRI.ArcGIS.Geometry;
using System.Windows.Forms;
using ESRI.ArcGIS.ADF;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Display;
using ESRI.ArcGIS.DataSourcesGDB;
using stdole;


using ESRI.ArcGIS.DataManagementTools;
using ESRI.ArcGIS.DataSourcesFile;
using ESRI.ArcGIS.ConversionTools;
using System.Runtime.InteropServices;
using PlanningGIS.Framework;
using PlanningGIS.Util.Convertor;
using PlanningGIS.ArcGIS.Custom;
using PlanningGIS.ArcGIS;
using PlanningGIS.Util.Log;

namespace PlanningGIS.DataConvert.model
{
    /// <summary>
    /// 作用：DLG数据转换实现类，支持FeatureClass到FeatureClass（如dgn(v7)或者GeoDatabase到GeoDatabase）
    /// </summary>
    public class DlgDataConvert : DataConvert
    {
        /// <summary>
        /// 是否利用Append GP工具
        /// </summary>
        private bool useAppendGP = false;

        /// <summary>
        /// 是否利用FeatClass2FeatClass GP工具
        /// </summary>
        private bool useFc2fcGp = false;

        /// <summary>
        /// 目标要素类名
        /// </summary>
        public string TargetFeatClsName { protected get; set; }

        /// <summary>
        /// 工作空间类型
        /// </summary>
        public zjgisWorkspaceType WorkspaceType { protected get; set; }

        /// <summary>
        /// 路径
        /// </summary>
        public string Path { protected get; set; }

        /// <summary>
        /// 源与目标的字段对应关系
        /// </summary>
        public Hashtable FieldRelation { get; set; }

        /// <summary>
        /// 目标字段的默认获得值，如果源数据中找不到对应的字段，则用该值
        /// </summary>
        public Hashtable FieldDefaultValue { get; set; }

        /// <summary>
        /// 入库依据字段，如果该变量不为空字符（""），则根据代码转换，代码关系由下面哈希表提供；否则直接转换
        /// </summary>
        public string SourceCodeName { get; set; }

        /// <summary>
        /// 记录数据源与目标数据的代码对应关系(对于一个转换，因为几何类型是一定的，所以只需要一个哈希表就可以了)
        /// </summary>
        public Hashtable FcodeRelation { protected get; set; }

        /// <summary>
        /// 数据源
        /// </summary>
        public IFeatureClass SourceFeatCls { get; set; }

        /// <summary>
        /// 是否通过Append GP进行数据转换
        /// </summary>
        public bool UseAppendGP
        {
            set
            {
                useAppendGP = value;
                if (useAppendGP) useFc2fcGp = false;
            }
        }

        /// <summary>
        /// 是否通过FeatClass2FeatClass GP进行数据转换
        /// </summary>
        public bool UseFc2fcGP
        {
            set
            {
                useFc2fcGp = value;
                if (useFc2fcGp) useAppendGP = false;
            }
        }

        /// <summary>
        /// 数据转换
        /// </summary>
        /// <returns></returns>
        public override bool Operate()
        {
            base.Operate();
            stopAnyway = false;
            ErrorCount = 0;
            RightCount = 0;

            //没有源或不符合要求
            if (SourceFeatCls == null)
            {
                LogHelper.WriteErrLog("请设置数据源。");
                return false;
            }
            bool result;
            if (useAppendGP)
                result = ConvertByAppendGpTool();
            else if (useFc2fcGp)
                result = ConvertByFc2fcGpTool();
            else
                result = ConvertByInterface();
            

            if (IsDelNullData) //删除空要素图层
            {
                if (TargetFeatCls == null) return result;
                if (TargetFeatCls.FeatureCount(null) > 0) return result;
                IDataset pDataset = TargetFeatCls as IDataset;
                if (!pDataset.CanDelete())
                {
                    LogHelper.WriteErrLog("[" + TargetFeatCls.AliasName + "]导出完毕后并无要素，但该数据可能被某程序占用，无法删除！\n");
                }
                else
                {
                    try
                    {
                        pDataset.Delete();
                        LogHelper.WriteDoneLog("[" + TargetFeatCls.AliasName + "]导出完毕后并无要素，系统将其要素类自动删除。\n");
                    }
                    catch (Exception ex)
                    {
                        LogHelper.WriteErrLog("[" + TargetFeatCls.AliasName + "]导出完毕后并无要素，但系统自动删除该要素失败：" + ex.Message + "\n");
                    }
                }
            }
            return result;
        }

        #region Private functions

        /// <summary>
        /// 通过AE接口进行数据转换
        /// </summary>
        /// <returns></returns>
        private bool ConvertByInterface()
        {
            int count = 0;
            ErrorCount = 0;
            RightCount = 0;
            try
            {
                if (!(SourceFeatCls.FeatureType == esriFeatureType.esriFTCoverageAnnotation && TargetFeatCls.FeatureType == esriFeatureType.esriFTAnnotation))
                {
                    if (SourceFeatCls.FeatureType != TargetFeatCls.FeatureType)
                    {
                        LogHelper.WriteErrLog("目标数据[" + TargetFeatCls.AliasName + "]与源数据要素类型不一致，不能转换！");
                        return false;
                    }
                    if (SourceFeatCls.ShapeType != TargetFeatCls.ShapeType)
                    {
                        LogHelper.WriteErrLog("目标数据[" + TargetFeatCls.AliasName + "]与源数据几何类型不一致，不能转换！");
                        return false;
                    }
                }
                //modified at 2009-11-28 所有对原始数据的删除都开编辑
                //modified at 2011-10-22 对本地数据，还是不用打开编辑了，否则太吃内存，下同
                bool needInEditSessionSource = NeedInEditSession(SourceFeatCls) & NeedDelete;  //数据源要删除的话，是否需要开打编辑
                //modified at 2009-04-29 所有转换都开编辑
                bool needInEditSeesionTarget = NeedInEditSession(TargetFeatCls);//创建目标要素时，是否需要打开编辑
                if (needInEditSessionSource) StartEdit(SourceFeatCls);
                if (needInEditSeesionTarget) StartEdit(TargetFeatCls);
                string fullSourcePath;
                IDataset pDataset = SourceFeatCls as IDataset;
                if (SourceFeatCls.FeatureDataset != null)
                {
                    fullSourcePath = PlanningGIS.ArcGIS.WorkspaceHelper.GetConnectionAffix(pDataset.Workspace) + "\\" + SourceFeatCls.FeatureDataset.Name + "\\" + pDataset.Name;
                }
                else
                {
                    fullSourcePath = PlanningGIS.ArcGIS.WorkspaceHelper.GetConnectionAffix(pDataset.Workspace) + "\\" + pDataset.Name;
                }
                TotalCount = SourceFeatCls.FeatureCount(SpatialFilter);
                setProcessBarMax.Invoke(TotalCount);
                if (TotalCount == 0) return true;
                LogHelper.WriteLog("正在将数据源[" + fullSourcePath + "]中的要素入到目标要素类[" + TargetFeatCls.AliasName + "]中...");
                IFeatureCursor pFeatCurSource = SourceFeatCls.Search(SpatialFilter, false);
                IFeature pSourceFeature;
                bool deleteErr = false;
                ArrayList errFieldindexs = new ArrayList();
                IFeatureCursor pTargetFeatCursor = TargetFeatCls.Insert(true);
                IFeatureBuffer pTargetFeatBuffer;                
                IFeatureClassLoad pFeatClsLod = TargetFeatCls as IFeatureClassLoad;
                if (pFeatClsLod != null) pFeatClsLod.LoadOnlyMode = true;
                while ((pSourceFeature = pFeatCurSource.NextFeature()) != null)
                {
                    if (stopAnyway)
                    {
                        if (pFeatClsLod != null) pFeatClsLod.LoadOnlyMode = false;
                        return false;
                    }
                    count++;
                    setProcessBarCurrent(count);
                    pTargetFeatBuffer = TargetFeatCls.CreateFeatureBuffer();
                    if (!SetAllAttributeValue(pSourceFeature, count, pTargetFeatBuffer, ref errFieldindexs))
                    {
                        ErrorCount++;
                        continue;
                    }

                    switch (pSourceFeature.FeatureType)
                    {
                        case esriFeatureType.esriFTSimple:
                            if (!SetShapeValue(pSourceFeature.ShapeCopy, count, pTargetFeatBuffer, pSourceFeature.OID))
                            {
                                ErrorCount++;
                                continue;
                            }
                            break;

                        case esriFeatureType.esriFTAnnotation:

                            if (!SetAnnoValue(pSourceFeature as IAnnotationFeature, pTargetFeatBuffer as IAnnotationFeature))
                            {
                                ErrorCount++;
                                continue;
                            }
                            break;

                        case esriFeatureType.esriFTCoverageAnnotation:
                            if (!SetAnnoAttributesFromDgnAnno(pSourceFeature, pTargetFeatBuffer))
                            {
                                ErrorCount++;
                                continue;
                            }
                            break;

                        default://其它类型暂不支持
                            ErrorCount++;
                            continue;
                    }

                    //插入要素
                    try
                    {
                        pTargetFeatCursor.InsertFeature(pTargetFeatBuffer);

                        try
                        {
                            if (NeedDelete) pSourceFeature.Delete();
                        }
                        catch (Exception e)
                        {
                            //报一次就可以了
                            if (!deleteErr)
                            {
                                deleteErr = true;
                                LogHelper.WriteErrLog("删除数据源[" + SourceFeatCls.AliasName + "]中的要素出错：" + e.Message);
                            }
                        }
                    }
                    catch (Exception e)
                    {
                        LogHelper.WriteErrLog("要素[" + pSourceFeature.OID + "]转换失败：" + e.Message);
                        ErrorCount++;
                        continue;
                    }

                    pDataset = TargetFeatCls as IDataset;

                    //modified at 2009-05-13 如果总数在10万条记录以内，则每转1千条保存一次，否则每转1万条保存一次
                    //modified at 2009-08-05 由于导出mdb数据，在做过以下动作之后，再次执行pTargetFeatCursor.InsertFeature
                    //会报组建错误，所以这里暂时对mdb数据，不分多次Flush
                    //modified at 2009-9-27先将游标释放，然后再打开编辑，插入游标，就可以不考虑是什么类型了（mdb也支持了）
                    if (((TotalCount <= 100000) ? (count % 1000 == 0) : (count % 10000 == 0))) //&& 
                    {
                        pTargetFeatCursor.Flush();
                        if (needInEditSeesionTarget) StopEidt(TargetFeatCls);

                        Marshal.ReleaseComObject(pTargetFeatCursor);
                        GC.Collect();

                        if (needInEditSeesionTarget) StartEdit(TargetFeatCls);
                        pTargetFeatCursor = TargetFeatCls.Insert(true);

                        //added at 2009-11-28 
                        #region 原始数据的删除与目标数据的新增保持同步
                        try
                        {
                            if (needInEditSessionSource)
                            {
                                StopEidt(SourceFeatCls);
                                StartEdit(SourceFeatCls);
                            }
                        }
                        catch (Exception e)
                        {
                            //报一次就可以了
                            if (!deleteErr)
                            {
                                deleteErr = true;
                                LogHelper.WriteErrLog("保存删除过后的数据源出现异常，删除源数据失败！" + e.Message + "\n");
                            }
                        }
                        #endregion
                    }

                    RightCount++;

                    if (System.Runtime.InteropServices.Marshal.IsComObject(pSourceFeature))
                        Marshal.ReleaseComObject(pSourceFeature);

                    if (System.Runtime.InteropServices.Marshal.IsComObject(pTargetFeatBuffer))
                        Marshal.ReleaseComObject(pTargetFeatBuffer);

                    Application.DoEvents();
                    if (stopAnyway)
                        return false;
                }

                pTargetFeatCursor.Flush();

                if (pFeatClsLod != null) pFeatClsLod.LoadOnlyMode = false;

                errFieldindexs = null;

                Marshal.ReleaseComObject(pFeatCurSource);
                GC.Collect();

                //如果保存目标要素失败，则表示所有的要素入库都失败
                try
                {
                    if (needInEditSeesionTarget) StopEidt(TargetFeatCls);
                    Marshal.ReleaseComObject(pTargetFeatCursor);
                }
                catch (Exception e)
                {
                    RightCount = 0;
                    ErrorCount = TotalCount;
                    LogHelper.WriteErrLog("保存目标数据出现异常：" + e.Message + "待转换的" + TotalCount + "个要素均导入失败！\n");
                }
                try
                {
                    if (needInEditSessionSource) StopEidt(SourceFeatCls);
                }
                catch (Exception e)
                {
                    LogHelper.WriteErrLog("保存删除过后的数据源出现异常，删除源数据失败！" + e.Message + "\n");
                }

                if (ErrorCount == 0)
                    LogHelper.WriteDoneLog("转换完毕。待转换总数：" + TotalCount + "；成功：" + RightCount + "；失败：" + ErrorCount + "\n");
                else
                    LogHelper.WriteErrLog("转换完毕。待转换总数：" + TotalCount + "；成功：" + RightCount + "；失败：" + ErrorCount + "\n");

                return true;
            }
            catch (Exception e)
            {
                RightCount = 0;
                ErrorCount = TotalCount;

                LogHelper.WriteErrLog("转换失败：" + e.Message + "\n");
                return false;
            }
        }

        /// <summary>
        /// 通过Append GP工具进行数据转换，不能设置过滤条件和代码对应关系
        /// </summary>
        /// <returns></returns>
        private bool ConvertByAppendGpTool()
        {
            try
            {
                bool success;
                IDataset pDataset = SourceFeatCls as IDataset;
                string sourcePath;
                if (SourceFeatCls.FeatureDataset != null)
                {
                    sourcePath = PlanningGIS.ArcGIS.WorkspaceHelper.GetConnectionAffix(pDataset.Workspace) + "\\" + SourceFeatCls.FeatureDataset.Name + "\\" + pDataset.Name;
                }
                else
                {
                    sourcePath = PlanningGIS.ArcGIS.WorkspaceHelper.GetConnectionAffix(pDataset.Workspace) + "\\" + pDataset.Name;
                }

                pDataset = TargetFeatCls as IDataset;
                string targetPath;
                if (TargetFeatCls.FeatureDataset != null)
                {
                    IFeatureLayer pFeatLyr = new FeatureLayerClass();
                    pFeatLyr.FeatureClass = TargetFeatCls;
                    IDataset pDs = pFeatLyr as IDataset;

                    targetPath = PlanningGIS.ArcGIS.WorkspaceHelper.GetConnectionAffix(pDataset.Workspace) + "\\" + TargetFeatCls.FeatureDataset.Name + "\\" + pDataset.Name;
                }
                else
                {
                    targetPath = PlanningGIS.ArcGIS.WorkspaceHelper.GetConnectionAffix(pDataset.Workspace) + "\\" + pDataset.Name;
                }

                LogHelper.WriteLog("正在将数据源[" + sourcePath + "]中的要素入到目标要素类[" + TargetFeatCls.AliasName + "]中...");

                Append append = new Append();
                append.inputs = sourcePath;
                append.target = targetPath;
                append.schema_type = "NO_TEST";

                #region 设置字段对应关系
                if (FieldRelation != null && FieldRelation.Count > 0)
                {
                    string fieldMap = "";
                    foreach (object key in FieldRelation.Keys)
                    {
                        string targetFieldName = key.ToString();
                        string sourceFieldName = FieldRelation[key].ToString();

                        if (sourceFieldName == "") continue;

                        string targetFieldAliasName = TargetFeatCls.Fields.get_Field(TargetFeatCls.FindField(targetFieldName)).AliasName;

                        IField pField = SourceFeatCls.Fields.get_Field(SourceFeatCls.FindField(sourceFieldName));
                        switch (pField.Type)
                        {
                            case esriFieldType.esriFieldTypeGlobalID:
                                fieldMap = fieldMap + targetFieldName + " '" + targetFieldAliasName + "' false false true 38 Text 0 0,First,#," + sourcePath + "," + sourceFieldName + ",-1,-1;";
                                break;
                            case esriFieldType.esriFieldTypeSmallInteger:
                                fieldMap = fieldMap + targetFieldName + " '" + targetFieldAliasName + "' " + pField.IsNullable.ToString().ToLower() + " true false 2 Short 0 5,First,#," + sourcePath + "," + sourceFieldName + ",-1,-1;";
                                break;

                            case esriFieldType.esriFieldTypeInteger:
                                fieldMap = fieldMap + targetFieldName + " '" + targetFieldAliasName + "' " + pField.IsNullable.ToString().ToLower() + " true false 4 Long 0 0,First,#," + sourcePath + "," + sourceFieldName + ",-1,-1;";
                                break;

                            case esriFieldType.esriFieldTypeString:
                                fieldMap = fieldMap + targetFieldName + " '" + targetFieldAliasName + "' " + pField.IsNullable.ToString().ToLower() + " true false 255 Text 0 0,First,#," + sourcePath + "," + sourceFieldName + ",-1,-1;";
                                break;

                            case esriFieldType.esriFieldTypeDouble:
                                fieldMap = fieldMap + targetFieldName + " '" + targetFieldAliasName + "' " + pField.IsNullable.ToString().ToLower() + " true false 0 Double 0 0,First,#," + sourcePath + "," + sourceFieldName + ",-1,-1;";
                                break;

                            case esriFieldType.esriFieldTypeBlob:
                                fieldMap = fieldMap + targetFieldName + " '" + targetFieldAliasName + "' " + pField.IsNullable.ToString().ToLower() + " true false 0 Blob 0 0,First,#," + sourcePath + "," + sourceFieldName + ",-1,-1;";
                                break;

                            default:   //有待完善更多的字段类型
                                fieldMap = fieldMap + targetFieldName + " '" + targetFieldAliasName + "', First,#," + sourcePath + ", " + sourceFieldName + ",-1,-1;";
                                break;
                        }
                    }

                    if (fieldMap != "")
                    {
                        fieldMap = fieldMap.Substring(0, fieldMap.Length - 1);
                        append.field_mapping = fieldMap;
                    }
                }
                #endregion

                string strMsg;
                success = GeoprocessorHelper.Execute(append, out strMsg);

                if (success)
                {
                    LogHelper.WriteDoneLog(strMsg);

                }
                else
                {
                    LogHelper.WriteErrLog(strMsg);
                }
                return success;
            }
            catch (Exception ex)
            {
                LogHelper.WriteErrLog("转换失败：" + ex.Message + "\n");
                return false;
            }
        }

        /// <summary>
        /// 通过FeatureClassToFeatureClass GP工具进行数据转换
        /// </summary>
        /// <returns></returns>
        private bool ConvertByFc2fcGpTool()
        {
            string fcName = (SourceFeatCls as IDataset).Name.Contains('.') ? (SourceFeatCls as IDataset).Name.Split('.')[1] : (SourceFeatCls as IDataset).Name;
            setProcessBarCurrent.Invoke(0);

            try
            {
                IFeatureLayer pFeatLyrOld = new FeatureLayerClass();
                pFeatLyrOld.FeatureClass = SourceFeatCls;

                IFeatureSelection pFeatSel = pFeatLyrOld as IFeatureSelection;

                IGeometry pPolygonExtent = null;
                IPolyline pPolyline = null;
                ITopologicalOperator2 pTop = null;
                string sql = "";

                bool hasZ = SourceFeatCls.HasZValue();

                #region 获取过滤器的图形条件和属性条件
                if (SpatialFilter != null)
                {
                    pPolygonExtent = SpatialFilter.Geometry;

                    if (pPolygonExtent != null && pPolygonExtent.IsEmpty == false)
                    {
                        if (hasZ)
                        {
                            pPolygonExtent = GeometryHelper.Geom2Dto3D(pPolygonExtent);
                        }
                        else
                        {
                            pPolygonExtent = GeometryHelper.Geom3Dto2D(pPolygonExtent);
                        }

                        pTop = pPolygonExtent as ITopologicalOperator2;
                        pTop.IsKnownSimple_2 = false;
                        pTop.Simplify();
                        pPolyline = pTop.Boundary as IPolyline;
                    }

                    sql = SpatialFilter.WhereClause;
                }
                #endregion

                #region 获取工作区类型
                IWorkspace pWorkspace = null;
                string wsPath = ""; //workspacePath
                IWorkspaceFactory pWorkspaceFactory = null;
                switch (WorkspaceType)
                {
                    case zjgisWorkspaceType.shp:
                        wsPath = Path;
                        pWorkspaceFactory = new ShapefileWorkspaceFactoryClass();
                        break;

                    case zjgisWorkspaceType.mdb:
                        wsPath = Path + ".mdb";
                        pWorkspaceFactory = new AccessWorkspaceFactoryClass();
                        break;

                    case zjgisWorkspaceType.gdb:
                        wsPath = Path + ".gdb";
                        pWorkspaceFactory = new FileGDBWorkspaceFactoryClass();
                        break;

                    default:
                        LogHelper.WriteErrLog("暂不支持该数据类型快速的导入！");
                        return false;
                }
                #endregion

                #region 打开工作区
                pWorkspace = pWorkspaceFactory.OpenFromFile(wsPath, 0);

                if (pWorkspace == null)
                {
                    LogHelper.WriteErrLog("打开工作区失败！");
                    return false;
                }
                #endregion

                IFieldChecker pFieldChecker;
                pFieldChecker = new FieldCheckerClass();
                pFieldChecker.ValidateWorkspace = pWorkspace;

                IWorkspace2 pWorkspace2 = pWorkspace as IWorkspace2;
                string out_path = wsPath;

                LogHelper.WriteLog("正在导出[" + fcName + "]中的数据...");

                ISelectionSet pSelset = CursorHelper.GetSelset(pFeatSel, pPolygonExtent, sql, esriSpatialRelEnum.esriSpatialRelIntersects);

                #region 判断数据集是否存在与目标工作空间中

                IFeatureDataset pFeatDStarget = null;
                if (SourceFeatCls.FeatureDataset != null && WorkspaceType != zjgisWorkspaceType.shp)
                {
                    IFeatureDataset pFeatDSsource = SourceFeatCls.FeatureDataset;
                    string fixedDatasetName;
                    string datasetName = pFeatDSsource.Name;
                    if (datasetName.Contains('.')) datasetName = datasetName.Split('.')[1];

                    pFieldChecker.ValidateTableName(datasetName, out fixedDatasetName);

                    if (pWorkspace2 != null)
                    {
                        if (pWorkspace2.get_NameExists(esriDatasetType.esriDTFeatureDataset, fixedDatasetName))
                        {
                            pFeatDStarget = (pWorkspace as IFeatureWorkspace).OpenFeatureDataset(fixedDatasetName);
                        }
                        else//如果不存在，需要先创建数据集
                        {
                            pFeatDStarget = (pWorkspace as IFeatureWorkspace).CreateFeatureDataset(fixedDatasetName,
                                (pFeatDSsource as IGeoDataset).SpatialReference);
                        }
                    }

                    out_path = out_path + "\\" + pFeatDStarget.Name;
                }
                #endregion

                TotalCount = pSelset.Count;

                if (TotalCount == 0)
                {
                    #region 如果需要更新的要素为0，则只需创建空要素类即可

                    if (IsDelNullData) return true;

                    if ((pWorkspace as IWorkspace2).get_NameExists(esriDatasetType.esriDTFeatureClass, fcName)) return true;

                    LogHelper.WriteLog("[" + fcName + "]要素类在导出范围内无数据，系统将创建空要素类...");

                    IFields pFields = SourceFeatCls.Fields;
                    IFields validatedFields = null;
                    IEnumFieldError enumFieldError = null;
                    pFieldChecker.Validate(pFields, out enumFieldError, out validatedFields);

                    #region Shape不能有GlobalID类型的字段
                    if (WorkspaceType == zjgisWorkspaceType.shp)
                    {
                        for (int i = 0; i < validatedFields.FieldCount; i++)
                        {
                            IField pField = validatedFields.get_Field(i);
                            if (pField.Type == esriFieldType.esriFieldTypeGlobalID) (validatedFields as IFieldsEdit).DeleteField(pField);
                        }
                    }
                    #endregion

                    if (pFeatDStarget != null)
                    {
                        TargetFeatCls = pFeatDStarget.CreateFeatureClass(fcName, validatedFields, null, null, esriFeatureType.esriFTSimple, SourceFeatCls.ShapeFieldName, "");
                    }
                    else
                    {
                        TargetFeatCls = (pWorkspace as IFeatureWorkspace).CreateFeatureClass(fcName, validatedFields, null, null, esriFeatureType.esriFTSimple, "Shape", "");
                    }

                    LogHelper.WriteDoneLog("[" + fcName + "]空要素类创建成功。\n");

                    #endregion
                }
                else
                {
                    #region 用FeatureClassToFeatureClass GP工具进行导出

                    TargetFeatCls = PlanningGIS.ArcGIS.GeodatabaseHelper.OpenFeatureClass(pWorkspace, fcName);

                    IFeatureLayerDefinition2 pFeatLyrDef = pFeatLyrOld as IFeatureLayerDefinition2;

                    IFeatureLayer pFeatLyrNew = pFeatLyrDef.CreateSelectionLayer(fcName, true, "", "");
                    
                    FeatureClassToFeatureClass fcTofc = new FeatureClassToFeatureClass();
                    fcTofc.in_features = pFeatLyrNew;
                    fcTofc.out_path = out_path;

                    string sourcePath;
                    IDataset pDataset = SourceFeatCls as IDataset;
                    if (SourceFeatCls.FeatureDataset != null)
                    {
                        sourcePath = PlanningGIS.ArcGIS.WorkspaceHelper.GetConnectionAffix(pDataset.Workspace) + "\\" + SourceFeatCls.FeatureDataset.Name + "\\" + pDataset.Name;
                    }
                    else
                    {
                        sourcePath = PlanningGIS.ArcGIS.WorkspaceHelper.GetConnectionAffix(pDataset.Workspace) + "\\" + pDataset.Name;
                    }

                    string fieldMap = "";
                    IFields fixedFields;
                    for (int i = 0; i < SourceFeatCls.Fields.FieldCount; i++)
                    {
                        IField pField = SourceFeatCls.Fields.get_Field(i);

                        IEnumFieldError error;
                        pFieldChecker.ValidateField(i, SourceFeatCls.Fields, out error, out fixedFields);
                        string targetFieldName = fixedFields.get_Field(i).Name;
                        string sourceFieldName = pField.Name;
                        string targetFieldAliasName = pField.AliasName;

                        if (pField.Type == esriFieldType.esriFieldTypeOID) continue;

                        switch (pField.Type)
                        {
                            case esriFieldType.esriFieldTypeGlobalID:
                                break;
                            case esriFieldType.esriFieldTypeSmallInteger:
                                fieldMap = fieldMap + targetFieldName + " '" + targetFieldAliasName + "' " + pField.IsNullable.ToString().ToLower() + " true false 2 Short 0 5,First,#," + sourcePath + "," + sourceFieldName + ",-1,-1;";
                                break;

                            case esriFieldType.esriFieldTypeInteger:
                                fieldMap = fieldMap + targetFieldName + " '" + targetFieldAliasName + "' " + pField.IsNullable.ToString().ToLower() + " true false 4 Long 0 0,First,#," + sourcePath + "," + sourceFieldName + ",-1,-1;";
                                break;

                            case esriFieldType.esriFieldTypeString:
                                fieldMap = fieldMap + targetFieldName + " '" + targetFieldAliasName + "' " + pField.IsNullable.ToString().ToLower() + " true false 255 Text 0 0,First,#," + sourcePath + "," + sourceFieldName + ",-1,-1;";
                                break;

                            case esriFieldType.esriFieldTypeDouble:
                                fieldMap = fieldMap + targetFieldName + " '" + targetFieldAliasName + "' " + pField.IsNullable.ToString().ToLower() + " true false 0 Double 0 0,First,#," + sourcePath + "," + sourceFieldName + ",-1,-1;";
                                break;

                            case esriFieldType.esriFieldTypeBlob:
                                fieldMap = fieldMap + targetFieldName + " '" + targetFieldAliasName + "' " + pField.IsNullable.ToString().ToLower() + " true false 0 Blob 0 0,First,#," + sourcePath + "," + sourceFieldName + ",-1,-1;";
                                break;

                            default:   //有待完善更多的字段类型
                                fieldMap = fieldMap + targetFieldName + " '" + targetFieldAliasName + "', First,#," + sourcePath + ", " + sourceFieldName + ",-1,-1;";
                                break;
                        }
                    }

                    if (fieldMap != "")
                    {
                        fieldMap = fieldMap.Substring(0, fieldMap.Length - 1);
                        fcTofc.field_mapping = fieldMap;
                    }

                    fcTofc.out_name = TargetFeatClsName;// fcName;

                    string strMsg;
                    bool success = GeoprocessorHelper.Execute(fcTofc, out strMsg);

                    if (success)
                    {
                        RightCount = TotalCount;
                        ErrorCount = 0;
                        LogHelper.WriteDoneLog(strMsg);
                        LogHelper.WriteDoneLog("该要素类导出数据量为：" + TotalCount + "个。\n");
                        TargetFeatCls = PlanningGIS.ArcGIS.GeodatabaseHelper.OpenFeatureClass(pWorkspace, TargetFeatClsName);
                    }
                    else
                    {
                        RightCount = 0;
                        ErrorCount = TotalCount;
                        LogHelper.WriteErrLog(strMsg);
                        return false;
                    }

                    pFeatSel.Clear();

                    #endregion

                    #region 与更新范围边界的数据进行裁切
                    IFeatureClass pFeatClsGdb = (pWorkspace as IFeatureWorkspace).OpenFeatureClass(fcName);

                    if (NeedCut && pPolygonExtent != null && pPolygonExtent.IsEmpty == false)
                    {
                        if (pFeatClsGdb == null) return false;
                        if (pFeatClsGdb.FeatureType == esriFeatureType.esriFTAnnotation) return true;  //注记不用裁切
                        if (pFeatClsGdb.ShapeType == esriGeometryType.esriGeometryPoint) return true;  //点要素类不用裁切

                        (pTop as IGeometry).Project((pFeatClsGdb as IGeoDataset).SpatialReference);
                        (pPolygonExtent as IGeometry).Project((pFeatClsGdb as IGeoDataset).SpatialReference);

                        LogHelper.WriteLog("开始对该数据的要素进行裁切...");

                        //开1米缓冲再搜，否则有些与导出边界Touch又在导出范围以外的要素会漏裁切
                        IGeometry pGeomBuffer = null;
                        //虽然直接拿边界开缓冲进行搜索会提高效率，但是考虑到有些多part要素正好在边界处是断开的，如果用边界搜索，则会导致
                        //这些要素裁切不成功，所以直接拿范围面做缓冲进行裁切，后面再判断该范围面是否完全包含要素，若是则可直接跳过
                        //pGeomBuffer = GeometryHelper.GetBuffer(pFeatClsGdb, pPolyline, 1);
                        //pGeomBuffer = GeometryHelper.GetBuffer(pPolygonExtent, 1);   //反正是对范围面搜索，没必要开缓冲了
                        if (pGeomBuffer == null || pGeomBuffer.IsEmpty) pGeomBuffer = pPolygonExtent;

                        if (hasZ)
                        {
                            pGeomBuffer = GeometryHelper.Geom2Dto3D(pGeomBuffer);
                        }
                        else
                        {
                            pGeomBuffer = GeometryHelper.Geom3Dto2D(pGeomBuffer);
                        }

                        IRelationalOperator pRel = pPolygonExtent as IRelationalOperator;

                        SpatialFilter = new SpatialFilterClass();
                        SpatialFilter.GeometryField = pFeatClsGdb.ShapeFieldName;
                        SpatialFilter.Geometry = pGeomBuffer;// pPolyline;
                        SpatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects;

                        int cutCountMax = pFeatClsGdb.FeatureCount(SpatialFilter);
                        int cutCountErr = 0;

                        if (cutCountMax == 0)
                        {
                            LogHelper.WriteLog("该数据没有要素需要裁切。\n");
                        }
                        else
                        {
                            setProcessBarMax.Invoke(cutCountMax);
                            IFeatureCursor pFeatCur = pFeatClsGdb.Search(SpatialFilter, false);
                            IFeature pFeatCut;
                            int cutCount = 0;
                            while ((pFeatCut = pFeatCur.NextFeature()) != null)
                            {
                                cutCount++;
                                setProcessBarCurrent.Invoke(cutCount);

                                try
                                {
                                    IGeometry pShapeCopy = pFeatCut.ShapeCopy;

                                    ITopologicalOperator2 pTop2 = null;
                                    if (pShapeCopy.GeometryType != esriGeometryType.esriGeometryPoint)
                                    {
                                        pTop2 = pShapeCopy as ITopologicalOperator2;
                                        pTop2.IsKnownSimple_2 = false;
                                        pTop2.Simplify();
                                    }

                                    if (pRel.Contains(pShapeCopy)) continue;

                                    if (pShapeCopy.GeometryType == esriGeometryType.esriGeometryPolyline)
                                    {
                                        pShapeCopy = pTop.Intersect(pShapeCopy, esriGeometryDimension.esriGeometry1Dimension);
                                    }
                                    else if (pShapeCopy.GeometryType == esriGeometryType.esriGeometryPolygon)
                                    {
                                        pShapeCopy = pTop.Intersect(pShapeCopy, esriGeometryDimension.esriGeometry2Dimension);
                                    }

                                    if (pShapeCopy == null || pShapeCopy.IsEmpty)
                                    {
                                        pFeatCut.Delete();
                                    }
                                    else
                                    {
                                        if (hasZ)
                                        {
                                            pShapeCopy = GeometryHelper.Geom2Dto3D(pShapeCopy);
                                        }
                                        else
                                        {
                                            pShapeCopy = GeometryHelper.Geom3Dto2D(pShapeCopy);
                                        }

                                        pFeatCut.Shape = pShapeCopy;
                                        pFeatCut.Store();
                                    }
                                }
                                catch (Exception ex)
                                {
                                    cutCountErr++;
                                    LogHelper.WriteErrLog("裁切要素[" + pFeatCut.OID + "]失败：" + ex.Message);
                                }

                            }

                            Marshal.ReleaseComObject(pFeatCur);

                            if (cutCountErr == 0)
                            {
                                LogHelper.WriteDoneLog("裁切完毕。处理总数：" + cutCountMax + "个，成功：" + cutCountMax + "个，失败：0个。\n");
                            }
                            else
                            {
                                LogHelper.WriteErrLog("裁切完毕。处理总数：" + cutCountMax + "个，成功：" + (cutCountMax - cutCountErr) + "个，失败：" + cutCountErr + "个。\n");
                            }
                        }
                    }
                    #endregion
                }

                LogHelper.WriteDoneLog("[" + fcName + "]数据导出完毕。\n\n");
                return true;
            }
            catch (Exception ex)
            {
                ErrorCount = RightCount;
                LogHelper.WriteErrLog("[" + fcName + "]数据导出失败：" + ex.Message);
                return false;
            }
        }


        /// <summary>
        /// 如果要素类是远程数据库类型，并且进行过注册，那么对要素的修改必须要开打编辑
        /// </summary>
        /// <param name="pFeatCls"></param>
        /// <returns></returns>
        private bool NeedInEditSession(IFeatureClass pFeatCls)
        {
            IDataset pDataset = pFeatCls as IDataset;
            IWorkspace pWorkspace = pDataset.Workspace;
            if (pWorkspace.Type != esriWorkspaceType.esriRemoteDatabaseWorkspace) return false;
            bool IsRegistered;
            bool IsMovingEditsToBase;
            IVersionedObject3 versionObj = pFeatCls as IVersionedObject3;
            versionObj.GetVersionRegistrationInfo(out IsRegistered, out IsMovingEditsToBase);
            return IsRegistered;
        }

        /// <summary>
        /// 打开编辑
        /// </summary>
        /// <param name="pFeatCls"></param>
        private void StartEdit(IFeatureClass pFeatCls)
        {
            IDataset pDataset = pFeatCls as IDataset;
            IWorkspace pWorkspace = pDataset.Workspace;
            IWorkspaceEdit pWsEdit = pWorkspace as IWorkspaceEdit;
            pWsEdit.StartEditing(false);
            pWsEdit.StartEditOperation();
            return;
        }

        /// <summary>
        /// 结束编辑
        /// </summary>
        /// <param name="pFeatCls"></param>
        private void StopEidt(IFeatureClass pFeatCls)
        {
            IDataset pDataset = pFeatCls as IDataset;
            IWorkspace pWorkspace = pDataset.Workspace;
            IWorkspaceEdit pWsEdit = pWorkspace as IWorkspaceEdit;
            pWsEdit.StopEditOperation();
            pWsEdit.StopEditing(true);
            return;
        }

        #region 用IFeature.Store的方式创建要素
        /// <summary>
        /// 根据字段对应关系设置新建对象的所有属性信息
        /// </summary>
        /// <param name="pRow"></param>
        /// <param name="count"></param>
        /// <param name="pTargetFeatBuffer"></param>
        private bool SetAllAttributeValue(IRow pRow, int count, IFeature pTargetFeature, ref ArrayList errFieldindexs)
        {
            int targetFieldIndex;
            int sourceFieldIndex;

            //所有字段赋值
            foreach (object targetFieldName in FieldRelation.Keys)
            {
                sourceFieldIndex = pRow.Fields.FindField(FieldRelation[targetFieldName].ToString());
                targetFieldIndex = pTargetFeature.Fields.FindField(targetFieldName.ToString());

                if (targetFieldIndex == -1 ||
                    !TargetFeatCls.Fields.get_Field(targetFieldIndex).Editable) continue;

                //判断是否有默认值设置，就算有默认值，也以数据源的信息优先，只有当数据源找不到相关的字段时，才用默认值
                bool exsitDefaultValue = false;
                object objectFieldDefaultValue = null;
                if (FieldDefaultValue != null)
                {
                    foreach (object objDefaultValue in FieldDefaultValue.Keys)
                    {
                        if (objDefaultValue.ToString() == targetFieldName.ToString() &&
                            !String.IsNullOrEmpty(FieldDefaultValue[objDefaultValue].ToString()))
                        {
                            exsitDefaultValue = true;
                            objectFieldDefaultValue = FieldDefaultValue[objDefaultValue];
                            break;
                        }
                    }
                }

                if (!SetAttributeValue(pRow, pTargetFeature, FieldRelation[targetFieldName].ToString(), targetFieldIndex, count,
                    exsitDefaultValue, ref errFieldindexs)) return false;

            }

            return true;
        }

        /// <summary>
        /// 给目标要素赋属性
        /// </summary>
        /// <param name="pRow">数据源</param>
        /// <param name="pFeature">目标要素</param>
        /// <param name="fieldName">数据源字段，可以是表达式</param>
        /// <param name="index">目标要素字段序号</param>
        /// <param name="count">当前个数</param>
        private bool SetAttributeValue(IRow pRow, IFeature pFeature, string fieldName, int index, int count,
            bool exitDefaultValue, ref ArrayList errFieldindexs)
        {
            //首先判断是否是表达式
            bool isExpression;
            isExpression = fieldName.Contains('[');

            object value;

            bool err = false;//是否出现错误
            string msg = "";//错误信息

            try
            {
                if (isExpression)
                {
                    #region 需要进行表达式计算
                    //仅支持数值型和字符串型的表达式计算，而且类型必须一致，要么都是字符串型，要么都是数值型
                    if ((int)pFeature.Fields.get_Field(index).Type > 4)
                    {
                        msg = "计算目标字段[" + pFeature.Fields.get_Field(index).Name + "]表达式失败，目前只支持数字和字符串型的计算。";
                        return SetAttributeValueErrOccur(pRow, pFeature, index, count, msg, ref errFieldindexs);
                    }

                    Regex r = new Regex(@"\[\w*\]");
                    MatchCollection m = r.Matches(fieldName);

                    int numCount = 0;//表达式中对应数据源的字段为数值型的个数
                    int strCount = 0;//表达式中对应数据源的字段为字符串型的个数

                    string strResult = "";

                    foreach (Match match in m)
                    {
                        string subFieldName = match.Captures[0].ToString().Trim().Replace("[", "").Replace("]", "").Replace(" ", "");
                        int sourceFieldIndex = pRow.Fields.FindField(subFieldName);

                        #region 计算面积
                        //如果数据源中找得到“面积”、“长度”、“周长”字段的话，以字段的值优先
                        if (sourceFieldIndex == -1 && subFieldName == "面积")
                        {
                            if (pRow is IFeature)
                            {
                                if (((IFeature)pRow).Shape.GeometryType == esriGeometryType.esriGeometryPolygon)
                                {
                                    IArea pArea = ((IFeature)pRow).Shape as IArea;
                                    fieldName = fieldName.Replace(subFieldName.Trim(), pArea.Area.ToString());
                                }
                                else
                                {
                                    msg = "数据源[" + SourceFeatCls.AliasName + "]几何类型不是多边形，无法计算目标字段[" +
                                            pFeature.Fields.get_Field(index).Name + "]中的[" + subFieldName + "]。";
                                    err = true;
                                }
                            }
                            else
                            {
                                msg = "数据源[" + SourceFeatCls.AliasName + "]不是多要素类，无法计算目标字段[" +
                                    pFeature.Fields.get_Field(index).Name + "]中的[" + subFieldName + "]。";
                                err = true;
                            }
                            numCount++;
                        }
                        #endregion

                        #region 计算长度或者周长
                        else if (sourceFieldIndex == -1 && (subFieldName == "长度" || subFieldName == "周长"))
                        {
                            if (pRow is IFeature)
                            {
                                if (((IFeature)pRow).Shape.GeometryType == esriGeometryType.esriGeometryPolyline ||
                                    ((IFeature)pRow).Shape.GeometryType == esriGeometryType.esriGeometryPolygon)
                                {
                                    IPolyline pPolyline = ((IFeature)pRow).Shape as IPolyline;
                                    fieldName = fieldName.Replace((subFieldName.Trim()), pPolyline.Length.ToString());
                                }
                                else
                                {
                                    msg = "数据源[" + SourceFeatCls.AliasName + "]几何类型不是线，无法计算目标字段[" +
                                         pFeature.Fields.get_Field(index).Name + "]中的[" + subFieldName + "]。";
                                    err = true;
                                }
                            }
                            else
                            {
                                msg = "数据源[" + SourceFeatCls.AliasName + "]不是多要素类，无法计算目标字段[" +
                                    pFeature.Fields.get_Field(index).Name + "]中的[" + subFieldName + "]。";
                                err = true;
                            }
                            numCount++;
                        }
                        #endregion

                        #region 计算字段的值
                        else
                        {
                            //一旦有一个字段不存在，则整个算数表达式就不要算了
                            if (sourceFieldIndex < 0)
                            {
                                msg = "数据源[" + SourceFeatCls.AliasName + "]字段[" + subFieldName + "]不存在，表达式无法计算";
                                err = true;
                            }
                            else
                            {
                                //判断字段数字型和字符串型的个数。如果是数字，则需要计算；如果是字符串，则直接合并
                                if (pRow.Fields.get_Field(sourceFieldIndex).Type == esriFieldType.esriFieldTypeDouble ||
                                   pRow.Fields.get_Field(sourceFieldIndex).Type == esriFieldType.esriFieldTypeSingle ||
                                   pRow.Fields.get_Field(sourceFieldIndex).Type == esriFieldType.esriFieldTypeInteger ||
                                   pRow.Fields.get_Field(sourceFieldIndex).Type == esriFieldType.esriFieldTypeSmallInteger)
                                {
                                    //如果类型为数值型时为空，则取0
                                    if (pRow.get_Value(sourceFieldIndex) == null || Convert.IsDBNull(pRow.get_Value(sourceFieldIndex)) ||
                                        string.IsNullOrEmpty(pRow.get_Value(sourceFieldIndex).ToString()))
                                    {
                                        value = 0;
                                    }
                                    else
                                    {
                                        value = pRow.get_Value(sourceFieldIndex).ToString();
                                    }
                                    fieldName = fieldName.Replace(("[" + subFieldName.Trim() + "]"), value.ToString());
                                    numCount++;
                                }
                                //对于字符串型的计算，只能作合并，不管连接运算符是+ - * 还是/，一律用+作
                                else if (pRow.Fields.get_Field(sourceFieldIndex).Type == esriFieldType.esriFieldTypeString)
                                {
                                    //如果类型为字符串型时为空，则取空字符串""
                                    if (pRow.get_Value(sourceFieldIndex) == null || Convert.IsDBNull(pRow.get_Value(sourceFieldIndex)) ||
                                        string.IsNullOrEmpty(pRow.get_Value(sourceFieldIndex).ToString()))
                                    {
                                        value = "";
                                    }
                                    else
                                    {
                                        value = pRow.get_Value(sourceFieldIndex).ToString();
                                    }
                                    strResult = strResult + value;
                                    strCount++;
                                }
                            }
                        }
                        #endregion

                        if (err) return SetAttributeValueErrOccur(pRow, pFeature, index, count, msg, ref errFieldindexs);
                    }

                    if (m.Count > 0)
                    {
                        if (numCount == m.Count)//全部数字，直接计算
                        {
                            object objResult;
                            try
                            {
                                objResult = expression.Evalute(fieldName);
                            }
                            catch (Exception e)
                            {
                                msg = "计算目标字段[" + pFeature.Fields.get_Field(index).Name + "]表达式出错！" + e.Message;
                                return SetAttributeValueErrOccur(pRow, pFeature, index, count, msg, ref errFieldindexs);
                            }
                            pFeature.set_Value(index, objResult);
                            return true;
                        }
                        else if (strCount == m.Count)//全部字符串，直接赋值
                        {
                            pFeature.set_Value(index, strResult);
                            return true;
                        }
                        else
                        {
                            msg = "目标字段[" + pFeature.Fields.get_Field(index).Name +
                                "]的表达式对应的数据源字段既有数字型又有数值型，无法计算。";
                            err = true;
                        }
                    }
                    else
                    {
                        msg = "解析目标字段[" + pFeature.Fields.get_Field(index).Name + "]对应的表达式失败！";
                        err = true;
                    }

                    if (err) return SetAttributeValueErrOccur(pRow, pFeature, index, count, msg, ref errFieldindexs);
                    #endregion
                }
                else
                {
                    #region 不需要计算，直接赋值
                    int sourceFieldIndex = pRow.Fields.FindField(fieldName);

                    #region 默认值处理
                    //如果数据源字段不存在，而有默认值，则直接赋默认值
                    if (sourceFieldIndex == -1 && exitDefaultValue)
                    {
                        pFeature.set_Value(index, FieldDefaultValue[pFeature.Fields.get_Field(index).Name]);
                        return true;
                    }
                    #endregion

                    #region 空值处理
                    //如果数据源字段不存在，或者为空
                    if (sourceFieldIndex == -1 || pRow.get_Value(sourceFieldIndex) == null ||
                        Convert.IsDBNull(pRow.get_Value(sourceFieldIndex)) ||
                        string.IsNullOrEmpty(pRow.get_Value(sourceFieldIndex).ToString()))
                    {
                        msg = "数据源字段[" + fieldName + "]有值为空。";

                        return SetAttributeValueErrOccur(pRow, pFeature, index, count, msg, ref errFieldindexs);
                    }
                    #endregion

                    #region 处理旋转角度字段
                    try
                    {
                        if (AppConfig.SystemConfig.符号化.角度字段.Split(";".ToCharArray())[0] == fieldName)
                        {
                            //先取入库依据字段，如果没有，则到系统配置文件中取符号化依据字段
                            string fcodeName = SourceCodeName != "" ? SourceCodeName : FieldRelation[AppConfig.SystemConfig.符号化.符号化字段].ToString(); ;
                            if (fcodeName != "")
                            {
                                int fcodeIndex = pRow.Fields.FindField(fcodeName);
                                if (fcodeIndex >= 0)
                                {
                                    string fcodeValue = pRow.get_Value(fcodeIndex).ToString();

                                    //如果有代码转换关系，需要进行转换后再判断
                                    if (FcodeRelation != null && FcodeRelation.Contains(fcodeValue))
                                        fcodeValue = FcodeRelation[fcodeValue].ToString();

                                    //倒数第三位图形码为1，说明是无向点
                                    Match match = Regex.Match(fcodeValue, @"\d\d\d\d\d\d1\d\d");
                                    if (match.Success)
                                    {
                                        pFeature.set_Value(sourceFieldIndex, DBNull.Value);
                                        return true;
                                    }
                                }
                            }
                        }

                    }
                    catch (Exception ex)
                    {
                        LogHelper.WriteErrLog("对原始要素[" + pRow.OID + "]设置无向点的旋转角度为空失败，将以默认的形式进行处理！" + ex.Message);
                    }
                    #endregion

                    value = pRow.get_Value(sourceFieldIndex);

                    #region 代码转换
                    //如果有入库依据字段，代码对应关系，需判断是否要转换
                    if (SourceCodeName != "" && fieldName == SourceCodeName && FcodeRelation != null &&
                        FcodeRelation.ContainsKey(value.ToString()))
                    {
                        value = FcodeRelation[value.ToString()];

                        //modified by sheng at 2013-06-07 因为有些地方变态的要求分类代码为长整形字段
                        if (pFeature.Class.Fields.get_Field(index).Type == esriFieldType.esriFieldTypeInteger)
                        {
                            value = Int32.Parse(value.ToString());
                        }
                        else
                        {
                            value = value.ToString();
                        }

                    }
                    #endregion

                    pFeature.set_Value(index, value);

                    #endregion
                }
                return true;
            }
            catch (Exception e)
            {
                msg = "获取目标数据[" + pRow.OID + "]字段[" + pFeature.Fields.get_Field(index).Name + "]值出错：" + e.Message;
                //之所以这里count强行赋值为1，是为了每次出现异常都需要提示用户
                return SetAttributeValueErrOccur(pRow, pFeature, index, 1, msg, ref errFieldindexs);
            }

        }

        /// <summary>
        /// 转属性出错时，如果目标要素该属性可以为空，则直接赋空值，如果不能为空，则数值型赋为0，字符串型赋为""，再第一次出现时，给出提示；
        /// 否则转该要素时会出错，则记下所有出错的要素ID
        /// </summary>
        /// <param name="pRow"></param>
        /// <param name="pFeature"></param>
        /// <param name="fieldName"></param>
        /// <param name="index"></param>
        /// <param name="count"></param>
        /// <param name="msg"></param>
        /// <returns></returns>
        private bool SetAttributeValueErrOccur(IRow pRow, IFeature pFeature, int index, int count, string msg, ref ArrayList errFieldindexs)
        {
            //如果该字段以前没出过错，现在出错了，那么强行将count赋为1，这样可以给出提示，并将该字段的索引加入导errFieldindexs，下次就可以不用提示了
            if (!errFieldindexs.Contains(index))
            {
                count = 1;
                errFieldindexs.Add(index);
            }

            if (pFeature.Fields.get_Field(index).IsNullable)
            {
                pFeature.set_Value(index, DBNull.Value);
                //if (count == 1) LogHelper.WriteLog(msg + "系统自动将其对应的目标字段[" + pFeature.Fields.get_Field(index).AliasName + "]赋空值。");
                return true;
            }
            else
            {
                switch (pFeature.Fields.get_Field(index).Type)
                {
                    case esriFieldType.esriFieldTypeSmallInteger:
                    case esriFieldType.esriFieldTypeInteger:
                    case esriFieldType.esriFieldTypeDouble:
                    case esriFieldType.esriFieldTypeSingle:
                        pFeature.set_Value(index, 0);
                        //if (count == 1) LogHelper.WriteLog(msg + "系统自动将其对应的目标字段[" + pFeature.Fields.get_Field(index).AliasName + "]赋0");
                        return true;
                    case esriFieldType.esriFieldTypeString:
                        //if (count == 1) LogHelper.WriteLog(msg + "系统自动将其对应的目标字段[" + pFeature.Fields.get_Field(index).AliasName + "]赋空字符串（\"\"）");
                        pFeature.set_Value(index, "");
                        return true;
                    default:
                        LogHelper.WriteErrLog("要素[" + pRow.OID + "]转换失败！" + msg);
                        return false;
                }
            }

        }

        /// <summary>
        /// 设置新要素的图形
        /// </summary>
        /// <param name="pGeom"></param>
        /// <param name="count"></param>
        /// <param name="pTargetFeatBuffer"></param>
        /// <param name="pTargetFeatCursor"></param>
        /// <param name="oid"></param>
        private bool SetShapeValue(IGeometry pGeom, int count, IFeature pTargetFeature, int oid)
        {
            //shape字段赋值
            IFields pFields = TargetFeatCls.Fields;

            int index = pFields.FindField(TargetFeatCls.ShapeFieldName);
            IField pFieldShape = pFields.get_Field(index);
            IGeometryDef pGeometryDef = pFieldShape.GeometryDef;

            //裁切用
            esriGeometryDimension geomDimension = esriGeometryDimension.esriGeometry0Dimension;
            if (SourceFeatCls.ShapeType == esriGeometryType.esriGeometryPolyline)
            {
                geomDimension = esriGeometryDimension.esriGeometry1Dimension;
            }
            else if (SourceFeatCls.ShapeType == esriGeometryType.esriGeometryPolygon)
            {
                geomDimension = esriGeometryDimension.esriGeometry2Dimension;
            }

            //图形赋值
            try
            {
                if (pGeom == null)
                {
                    LogHelper.WriteErrLog("要素[" + oid + "]转换失败：图形为空！");
                    return false;
                }
                if (NeedCut && CutPolygon != null)
                    pGeom = GeometryHelper.CutFeatByPolygon(pGeom, CutPolygon, geomDimension);

                if (pGeometryDef.HasZ)
                    pGeom = GeometryHelper.Geom2Dto3D(pGeom);

                ITopologicalOperator2 pTop = pGeom as ITopologicalOperator2;

                if (pTop != null)
                {
                    pTop.IsKnownSimple_2 = false;
                    pTop.Simplify();
                }


                pTargetFeature.Shape = pGeom;

            }
            catch (Exception e)
            {
                LogHelper.WriteErrLog("要素[" + oid + "]转换失败：几何字段赋值出错！" + e.Message);
                return false;
            }

            return true;
        }

        /// <summary>
        /// 将dgn的注记传成arcinfo的注记
        /// </summary>
        /// <param name="pFeature"></param>
        /// <param name="count"></param>
        /// <param name="pTargetFeatBuffer"></param>
        /// <param name="pTargetFeatCursor"></param>
        private bool SetAnnoAttributesFromDgnAnno(IFeature pSourceFeature, IFeature pTargetFeature)
        {
            try
            {
                IFields pFields = pSourceFeature.Fields;

                if (!(pTargetFeature is IAnnotationFeature))
                {
                    LogHelper.WriteErrLog("注记[" + pSourceFeature.OID + "]转换出错：目标数据类型不匹配！");
                    return false;
                }
                IAnnotationFeature pAnnotationFeature = pTargetFeature as IAnnotationFeature;
                ISymbolCollectionElement pSymClnEle = new TextElement() as ISymbolCollectionElement;

                for (int i = 0; i < pFields.FieldCount; i++)
                {
                    object obj = pSourceFeature.get_Value(i);
                    IField pField = pFields.get_Field(i);
                    switch (pField.Name.ToUpper())
                    {
                        case "TEXT":
                            string value = StringHelper.ConvertWRTNull(obj);
                            //如果既有半角又有全角，则全部转为全角
                            if (StringHelper.DSALL(value))
                            {
                                value = StringHelper.ToSBC(value);
                            }
                            pSymClnEle.Text = value;
                            break;

                        case "HEIGHT":
                            //到底是个怎么样的比列关系？
                            if (StringHelper.CanConvert2PositiveDouble(obj) && Double.Parse(obj.ToString()) > 0)
                                pSymClnEle.Size = Double.Parse(obj.ToString()) * 6;
                            else
                                pSymClnEle.Size = 0.65;

                            break;

                        case "TXTANGLE":
                            if (StringHelper.CanConvert2PositiveDouble(obj))
                                pSymClnEle.FlipAngle = Double.Parse(obj.ToString());
                            break;
                        default:
                            break;
                    }

                }
                pSymClnEle.HorizontalAlignment = esriTextHorizontalAlignment.esriTHALeft;
                pSymClnEle.VerticalAlignment = esriTextVerticalAlignment.esriTVABottom;
                pSymClnEle.FontName = "宋体";

                pSymClnEle.Geometry = pSourceFeature.ShapeCopy;

                IElement pElement = pSymClnEle as IElement;

                pAnnotationFeature.Annotation = pElement;

                //pTargetFeature.Store();
            }
            catch (Exception e)
            {

                LogHelper.WriteErrLog("注记[" + pSourceFeature.OID + "]转换出错！" + e.Message);
                return false;

            }
            return true;
        }

        #endregion

        #region 用IFeatureBuffer的方式创建要素
        /// <summary>
        /// 根据字段对应关系设置新建对象的所有属性信息
        /// </summary>
        /// <param name="pRow"></param>
        /// <param name="count"></param>
        /// <param name="pTargetFeatBuffer"></param>
        private bool SetAllAttributeValue(IRow pRow, int count, IFeatureBuffer pFeatureBufrer, ref ArrayList errFieldindexs)
        {
            int targetFieldIndex;
            int sourceFieldIndex;
            //对于注记，可以不需要有字段匹配关系
            if (FieldRelation == null || FieldRelation.Count == 0) return true;
            //所有字段赋值
            foreach (object targetFieldName in FieldRelation.Keys)
            {
                sourceFieldIndex = pRow.Fields.FindField(FieldRelation[targetFieldName].ToString());
                targetFieldIndex = pFeatureBufrer.Fields.FindField(targetFieldName.ToString());

                if (targetFieldIndex == -1 ||
                    !TargetFeatCls.Fields.get_Field(targetFieldIndex).Editable) continue;

                //判断是否有默认值设置，就算有默认值，也以数据源的信息优先，只有当数据源找不到相关的字段时，才用默认值
                bool exsitDefaultValue = false;
                object objectFieldDefaultValue = null;
                if (FieldDefaultValue != null)
                {
                    foreach (object objDefaultValue in FieldDefaultValue.Keys)
                    {
                        object obj = FieldDefaultValue[objDefaultValue];
                        if (obj == null) continue;
                        if (objDefaultValue.ToString() == targetFieldName.ToString() &&
                            !String.IsNullOrEmpty(obj.ToString()))
                        {
                            exsitDefaultValue = true;
                            objectFieldDefaultValue = obj;
                            break;
                        }
                    }
                }

                if (!SetAttributeValue(pRow, pFeatureBufrer, FieldRelation[targetFieldName].ToString(), targetFieldIndex, count,
                    exsitDefaultValue, ref errFieldindexs)) return false;

            }

            //如果数据源中有GlobalID字段，目标数据中有GlobalID2字段，则说明需要进行GUD的拷贝
            if (pRow.Fields.FindField("GlobalID") != -1 && pFeatureBufrer.Fields.FindField("GlobalID2") != -1)
            {
                SetAttributeValue(pRow, pFeatureBufrer, "GlobalID", pFeatureBufrer.Fields.FindField("GlobalID2"), count, false, ref errFieldindexs);
            }
            return true;
        }

        /// <summary>
        /// 给目标要素赋属性
        /// </summary>
        /// <param name="pRow">数据源</param>
        /// <param name="pFeature">目标要素</param>
        /// <param name="fieldName">数据源字段，可以是表达式</param>
        /// <param name="index">目标要素字段序号</param>
        /// <param name="count">当前个数</param>
        private bool SetAttributeValue(IRow pRow, IFeatureBuffer pFeatureBufrer, string fieldName, int index, int count,
            bool exitDefaultValue, ref ArrayList errFieldindexs)
        {
            //首先判断是否是表达式
            bool isExpression;
            isExpression = fieldName.Contains('[');

            object value;

            bool err = false;//是否出现错误
            string msg = "";//错误信息

            try
            {
                //pFeatureBufrer.Fields.get_Field(index).Editable 

                if (isExpression)
                {
                    #region 需要进行表达式计算
                    //仅支持数值型和字符串型的表达式计算，而且类型必须一致，要么都是字符串型，要么都是数值型
                    if ((int)pFeatureBufrer.Fields.get_Field(index).Type > 4)
                    {
                        msg = "计算目标字段[" + pFeatureBufrer.Fields.get_Field(index).Name + "]表达式失败，目前只支持数字和字符串型的计算。";
                        return SetAttributeValueErrOccur(pRow, pFeatureBufrer, index, count, msg, ref errFieldindexs);
                    }

                    Regex r = new Regex(@"\[\w*\]");
                    MatchCollection m = r.Matches(fieldName);

                    int numCount = 0;//表达式中对应数据源的字段为数值型的个数
                    int strCount = 0;//表达式中对应数据源的字段为字符串型的个数

                    string strResult = "";

                    foreach (Match match in m)
                    {
                        string subFieldName = match.Captures[0].ToString().Trim().Replace("[", "").Replace("]", "").Replace(" ", "");
                        int sourceFieldIndex = pRow.Fields.FindField(subFieldName);

                        #region 计算面积
                        //如果数据源中找得到“面积”、“长度”、“周长”字段的话，以字段的值优先
                        if (sourceFieldIndex == -1 && subFieldName == "面积")
                        {
                            if (pRow is IFeature)
                            {
                                if (((IFeature)pRow).Shape.GeometryType == esriGeometryType.esriGeometryPolygon)
                                {
                                    IArea pArea = ((IFeature)pRow).Shape as IArea;
                                    fieldName = fieldName.Replace(subFieldName.Trim(), pArea.Area.ToString());
                                }
                                else
                                {
                                    msg = "数据源[" + SourceFeatCls.AliasName + "]几何类型不是多边形，无法计算目标字段[" +
                                            pFeatureBufrer.Fields.get_Field(index).Name + "]中的[" + subFieldName + "]。";
                                    err = true;
                                }
                            }
                            else
                            {
                                msg = "数据源[" + SourceFeatCls.AliasName + "]不是多要素类，无法计算目标字段[" +
                                    pFeatureBufrer.Fields.get_Field(index).Name + "]中的[" + subFieldName + "]。";
                                err = true;
                            }
                            numCount++;
                        }
                        #endregion

                        #region 计算长度或者周长
                        else if (sourceFieldIndex == -1 && (subFieldName == "长度" || subFieldName == "周长"))
                        {
                            if (pRow is IFeature)
                            {
                                if (((IFeature)pRow).Shape.GeometryType == esriGeometryType.esriGeometryPolyline ||
                                    ((IFeature)pRow).Shape.GeometryType == esriGeometryType.esriGeometryPolygon)
                                {
                                    IPolyline pPolyline = ((IFeature)pRow).Shape as IPolyline;
                                    fieldName = fieldName.Replace((subFieldName.Trim()), pPolyline.Length.ToString());
                                }
                                else
                                {
                                    msg = "数据源[" + SourceFeatCls.AliasName + "]几何类型不是线，无法计算目标字段[" +
                                         pFeatureBufrer.Fields.get_Field(index).Name + "]中的[" + subFieldName + "]。";
                                    err = true;
                                }
                            }
                            else
                            {
                                msg = "数据源[" + SourceFeatCls.AliasName + "]不是多要素类，无法计算目标字段[" +
                                    pFeatureBufrer.Fields.get_Field(index).Name + "]中的[" + subFieldName + "]。";
                                err = true;
                            }
                            numCount++;
                        }
                        #endregion

                        #region 计算字段的值
                        else
                        {
                            //一旦有一个字段不存在，则整个算数表达式就不要算了
                            if (sourceFieldIndex < 0)
                            {
                                msg = "数据源[" + SourceFeatCls.AliasName + "]字段[" + subFieldName + "]不存在，表达式无法计算";
                                err = true;
                            }
                            else
                            {
                                //判断字段数字型和字符串型的个数。如果是数字，则需要计算；如果是字符串，则直接合并
                                if (pRow.Fields.get_Field(sourceFieldIndex).Type == esriFieldType.esriFieldTypeDouble ||
                                   pRow.Fields.get_Field(sourceFieldIndex).Type == esriFieldType.esriFieldTypeSingle ||
                                   pRow.Fields.get_Field(sourceFieldIndex).Type == esriFieldType.esriFieldTypeInteger ||
                                   pRow.Fields.get_Field(sourceFieldIndex).Type == esriFieldType.esriFieldTypeSmallInteger)
                                {
                                    //如果类型为数值型时为空，则取0
                                    if (pRow.get_Value(sourceFieldIndex) == null || Convert.IsDBNull(pRow.get_Value(sourceFieldIndex)) ||
                                        string.IsNullOrEmpty(pRow.get_Value(sourceFieldIndex).ToString()))
                                    {
                                        value = 0;
                                    }
                                    else
                                    {
                                        value = pRow.get_Value(sourceFieldIndex).ToString();
                                    }
                                    fieldName = fieldName.Replace(("[" + subFieldName.Trim() + "]"), value.ToString());
                                    numCount++;
                                }
                                //对于字符串型的计算，只能作合并，不管连接运算符是+ - * 还是/，一律用+作
                                else if (pRow.Fields.get_Field(sourceFieldIndex).Type == esriFieldType.esriFieldTypeString)
                                {
                                    //如果类型为字符串型时为空，则取空字符串""
                                    if (pRow.get_Value(sourceFieldIndex) == null || Convert.IsDBNull(pRow.get_Value(sourceFieldIndex)) ||
                                        string.IsNullOrEmpty(pRow.get_Value(sourceFieldIndex).ToString()))
                                    {
                                        value = "";
                                    }
                                    else
                                    {
                                        value = pRow.get_Value(sourceFieldIndex).ToString();
                                    }
                                    strResult = strResult + value;
                                    strCount++;
                                }
                            }
                        }
                        #endregion

                        if (err) return SetAttributeValueErrOccur(pRow, pFeatureBufrer, index, count, msg, ref errFieldindexs);
                    }

                    if (m.Count > 0)
                    {
                        if (numCount == m.Count)//全部数字，直接计算
                        {
                            object objResult;
                            try
                            {
                                objResult = expression.Evalute(fieldName);
                            }
                            catch (Exception e)
                            {
                                msg = "计算目标字段[" + pFeatureBufrer.Fields.get_Field(index).Name + "]表达式出错！" + e.Message;
                                return SetAttributeValueErrOccur(pRow, pFeatureBufrer, index, count, msg, ref errFieldindexs);
                            }
                            pFeatureBufrer.set_Value(index, objResult);
                            return true;
                        }
                        else if (strCount == m.Count)//全部字符串，直接赋值
                        {
                            pFeatureBufrer.set_Value(index, strResult);
                            return true;
                        }
                        else
                        {
                            msg = "目标字段[" + pFeatureBufrer.Fields.get_Field(index).Name +
                                "]的表达式对应的数据源字段既有数字型又有数值型，无法计算。";
                            err = true;
                        }
                    }
                    else
                    {
                        msg = "解析目标字段[" + pFeatureBufrer.Fields.get_Field(index).Name + "]对应的表达式失败！";
                        err = true;
                    }

                    if (err) return SetAttributeValueErrOccur(pRow, pFeatureBufrer, index, count, msg, ref errFieldindexs);
                    #endregion
                }
                else
                {
                    #region 不需要计算，直接赋值
                    int sourceFieldIndex = pRow.Fields.FindField(fieldName);

                    #region 默认值处理
                    //如果数据源字段不存在，而有默认值，则直接赋默认值
                    if (sourceFieldIndex == -1 && exitDefaultValue)
                    {
                        pFeatureBufrer.set_Value(index, FieldDefaultValue[pFeatureBufrer.Fields.get_Field(index).Name]);
                        return true;
                    }
                    #endregion

                    #region 空值处理
                    //如果数据源字段不存在，或者为空
                    if (sourceFieldIndex == -1 || pRow.get_Value(sourceFieldIndex) == null ||
                        Convert.IsDBNull(pRow.get_Value(sourceFieldIndex)) ||
                        string.IsNullOrEmpty(pRow.get_Value(sourceFieldIndex).ToString()))
                    {
                        msg = "数据源字段[" + fieldName + "]有值为空。";

                        return SetAttributeValueErrOccur(pRow, pFeatureBufrer, index, count, msg, ref errFieldindexs);
                    }
                    #endregion

                    #region 处理旋转角度字段
                    try
                    {
                        if (AppConfig.SystemConfig.符号化.角度字段.Split(";".ToCharArray())[0] == fieldName)
                        {
                            //先取入库依据字段，如果没有，则到系统配置文件中取符号化依据字段
                            string fcodeName = SourceCodeName != "" ? SourceCodeName : FieldRelation[AppConfig.SystemConfig.符号化.符号化字段].ToString(); ;
                            if (fcodeName != null && fcodeName != "")
                            {
                                int fcodeIndex = pRow.Fields.FindField(fcodeName);
                                if (fcodeIndex >= 0)
                                {
                                    string fcodeValue = pRow.get_Value(fcodeIndex).ToString();

                                    //如果有代码转换关系，需要进行转换后再判断
                                    if (FcodeRelation != null && FcodeRelation.Contains(fcodeValue))
                                        fcodeValue = FcodeRelation[fcodeValue].ToString();

                                    //倒数第三位图形码为1，说明是无向点
                                    Match match = Regex.Match(fcodeValue, @"\d\d\d\d\d\d1\d\d");
                                    if (match.Success)
                                    {
                                        pFeatureBufrer.set_Value(index, DBNull.Value);
                                        return true;
                                    }
                                }
                            }
                        }

                    }
                    catch (Exception ex)
                    {
                        LogHelper.WriteErrLog("对原始要素[" + pRow.OID + "]设置无向点的旋转角度为空失败，将以默认的形式进行处理！" + ex.Message);
                    }
                    #endregion

                    value = pRow.get_Value(sourceFieldIndex);

                    #region 代码转换
                    //如果有入库依据字段，代码对应关系，需判断是否要转换
                    if (SourceCodeName != "" && fieldName == SourceCodeName && FcodeRelation != null &&
                        FcodeRelation.ContainsKey(value.ToString()))
                        value = FcodeRelation[value.ToString()];
                    #endregion

                    pFeatureBufrer.set_Value(index, value);

                    #endregion
                }
                return true;
            }
            catch (Exception e)
            {
                msg = "获取目标数据[" + pRow.OID + "]字段[" + pFeatureBufrer.Fields.get_Field(index).Name + "]值出错：" + e.Message;
                //之所以这里count强行赋值为1，是为了每次出现异常都需要提示用户
                return SetAttributeValueErrOccur(pRow, pFeatureBufrer, index, 1, msg, ref errFieldindexs);
            }

        }

        /// <summary>
        /// 转属性出错时，如果目标要素该属性可以为空，则直接赋空值，如果不能为空，则数值型赋为0，字符串型赋为""，再第一次出现时，给出提示；
        /// 否则转该要素时会出错，则记下所有出错的要素ID
        /// </summary>
        /// <param name="pRow"></param>
        /// <param name="pFeature"></param>
        /// <param name="fieldName"></param>
        /// <param name="index"></param>
        /// <param name="count"></param>
        /// <param name="msg"></param>
        /// <returns></returns>
        private bool SetAttributeValueErrOccur(IRow pRow, IFeatureBuffer pFeatureBufrer, int index, int count, string msg, ref ArrayList errFieldindexs)
        {
            //如果该字段以前没出过错，现在出错了，那么强行将count赋为1，这样可以给出提示，并将该字段的索引加入导errFieldindexs，下次就可以不用提示了
            if (!errFieldindexs.Contains(index))
            {
                count = 1;
                errFieldindexs.Add(index);
            }

            if (pFeatureBufrer.Fields.get_Field(index).IsNullable)
            {
                pFeatureBufrer.set_Value(index, DBNull.Value);
                //if (count == 1) LogHelper.WriteLog(msg + "系统自动将其对应的目标字段[" + pFeatureBufrer.Fields.get_Field(index).AliasName + "]赋空值。");
                return true;
            }
            else
            {
                switch (pFeatureBufrer.Fields.get_Field(index).Type)
                {
                    case esriFieldType.esriFieldTypeSmallInteger:
                    case esriFieldType.esriFieldTypeInteger:
                    case esriFieldType.esriFieldTypeDouble:
                    case esriFieldType.esriFieldTypeSingle:
                        pFeatureBufrer.set_Value(index, 0);
                        //if (count == 1) LogHelper.WriteLog(msg + "系统自动将其对应的目标字段[" + pFeatureBufrer.Fields.get_Field(index).AliasName + "]赋0");
                        return true;
                    case esriFieldType.esriFieldTypeString:
                        //if (count == 1) LogHelper.WriteLog(msg + "系统自动将其对应的目标字段[" + pFeatureBufrer.Fields.get_Field(index).AliasName + "]赋空字符串（\"\"）");
                        pFeatureBufrer.set_Value(index, "");
                        return true;
                    default:
                        LogHelper.WriteErrLog("要素[" + pRow.OID + "]转换失败！" + msg);
                        return false;
                }
            }

        }

        /// <summary>
        /// 设置新要素的图形
        /// </summary>
        /// <param name="pGeom"></param>
        /// <param name="count"></param>
        /// <param name="pTargetFeatBuffer"></param>
        /// <param name="pTargetFeatCursor"></param>
        /// <param name="oid"></param>
        private bool SetShapeValue(IGeometry pGeom, int count, IFeatureBuffer pFeatureBuffer, int oid)
        {
            //shape字段赋值
            IFields pFields = TargetFeatCls.Fields;

            int index = pFields.FindField(TargetFeatCls.ShapeFieldName);
            IField pFieldShape = pFields.get_Field(index);
            IGeometryDef pGeometryDef = pFieldShape.GeometryDef;

            //裁切用
            esriGeometryDimension geomDimension = esriGeometryDimension.esriGeometry0Dimension;
            if (SourceFeatCls.ShapeType == esriGeometryType.esriGeometryPolyline)
            {
                geomDimension = esriGeometryDimension.esriGeometry1Dimension;
            }
            else if (SourceFeatCls.ShapeType == esriGeometryType.esriGeometryPolygon)
            {
                geomDimension = esriGeometryDimension.esriGeometry2Dimension;
            }

            //图形赋值
            try
            {
                if (pGeom == null)
                {
                    LogHelper.WriteErrLog("要素[" + oid + "]转换失败：图形为空！");
                    return false;
                }
                if (NeedCut && CutPolygon != null)
                    pGeom = GeometryHelper.CutFeatByPolygon(pGeom, CutPolygon, geomDimension);

                if (pGeometryDef.HasZ)
                    pGeom = GeometryHelper.Geom2Dto3D(pGeom);
                else
                    pGeom = GeometryHelper.Geom3Dto2D(pGeom);

                ITopologicalOperator2 pTop = pGeom as ITopologicalOperator2;
                if (pTop != null)
                {
                    pTop.IsKnownSimple_2 = false;
                    pTop.Simplify();
                }
                pGeom.Project(((pFeatureBuffer as IFeature).Class as IGeoDataset).SpatialReference);
                pFeatureBuffer.Shape = pGeom;
            }
            catch (Exception e)
            {
                LogHelper.WriteLog("要素[" + oid + "]转换失败：几何字段赋值出错！" + e.Message);
                return false;
            }
            return true;
        }

        /// <summary>
        /// 将dgn的注记传成arcinfo的注记
        /// </summary>
        /// <param name="pFeature"></param>
        /// <param name="count"></param>
        /// <param name="pTargetFeatBuffer"></param>
        /// <param name="pTargetFeatCursor"></param>
        private bool SetAnnoAttributesFromDgnAnno(IFeature pSourceFeature, IFeatureBuffer pFeatureBuffer)
        {
            try
            {
                IFields pFields = pSourceFeature.Fields;

                if (!(pFeatureBuffer is IAnnotationFeature))
                {
                    LogHelper.WriteErrLog("注记[" + pSourceFeature.OID + "]转换出错：目标数据类型不匹配！");
                    return false;
                }
                IAnnotationFeature pAnnotationFeature = pFeatureBuffer as IAnnotationFeature;
                ISymbolCollectionElement pSymClnEle = new TextElement() as ISymbolCollectionElement;

                for (int i = 0; i < pFields.FieldCount; i++)
                {
                    object obj = pSourceFeature.get_Value(i);
                    IField pField = pFields.get_Field(i);
                    switch (pField.Name.ToUpper())
                    {
                        case "TEXT":
                            string value = StringHelper.ConvertWRTNull(obj);
                            //如果既有半角又有全角，则全部转为全角
                            if (StringHelper.DSALL(value))
                            {
                                value = StringHelper.ToSBC(value);
                            }
                            pSymClnEle.Text = value;
                            break;

                        case "HEIGHT":
                            //到底是个怎么样的比列关系？
                            if (StringHelper.CanConvert2PositiveDouble(obj) && Double.Parse(obj.ToString()) > 0)
                                pSymClnEle.Size = Double.Parse(obj.ToString()) * 6;
                            else
                                pSymClnEle.Size = 0.65;

                            break;

                        case "TXTANGLE":
                            if (StringHelper.CanConvert2PositiveDouble(obj))
                                pSymClnEle.FlipAngle = Double.Parse(obj.ToString());
                            break;
                        default:
                            break;
                    }

                }
                pSymClnEle.HorizontalAlignment = esriTextHorizontalAlignment.esriTHALeft;
                pSymClnEle.VerticalAlignment = esriTextVerticalAlignment.esriTVABottom;
                pSymClnEle.FontName = "宋体";

                pSymClnEle.Geometry = pSourceFeature.ShapeCopy;

                IElement pElement = pSymClnEle as IElement;

                pAnnotationFeature.Annotation = pElement;

                //pTargetFeature.Store();
            }
            catch (Exception e)
            {
                LogHelper.WriteLog("注记[" + pSourceFeature.OID + "]转换出错！" + e.Message, zjgisLogType.zjgisLogError);
                return false;

            }
            return true;
        }

        #endregion

        /// <summary>
        /// 设置注记各个属性
        /// </summary>
        /// <param name="pAnnoFeatSource"></param>
        /// <param name="pAnnoFeatTarget"></param>
        /// <returns></returns>
        private bool SetAnnoValue(IAnnotationFeature pAnnoFeatSource, IAnnotationFeature pAnnoFeatTarget)
        {
            try
            {
                ITextElement pTxtElement = new TextElementClass();
                IElement pElement = pAnnoFeatSource.Annotation;
                if (!(pElement is ITextElement))
                {
                    LogHelper.WriteLog("要素[" + (pAnnoFeatSource as IFeature).OID + "转换失败：该注记要素为非文本类型！", zjgisLogType.zjgisLogError);
                    return false;
                }

                pTxtElement.Text = ((ITextElement)pAnnoFeatSource.Annotation).Text;
                pElement = pTxtElement as IElement;


                ITextSymbol pTextSymbol = new TextSymbolClass();

                pTextSymbol = ((ITextElement)pAnnoFeatSource.Annotation).Symbol;

                //modified at 2018-08-12 如果源和目标的参考比例尺大小不一样，那么需要乘以一个相应的比例
                IAnnotationClassExtension pAnnoFclsExtSur = ((pAnnoFeatSource as IFeature).Class as IFeatureClass).Extension as IAnnotationClassExtension;
                IAnnotationClassExtension pAnnoFclsExtTag = ((pAnnoFeatTarget as IFeature).Class as IFeatureClass).Extension as IAnnotationClassExtension;

                IFontDisp pFontDisp = (pAnnoFeatSource.Annotation as ITextElement).Symbol.Font;
                pFontDisp.Size = (pAnnoFeatSource.Annotation as ITextElement).Symbol.Font.Size;
                if (pAnnoFclsExtTag.ReferenceScale > 0)
                {
                    pFontDisp.Size = (pAnnoFeatSource.Annotation as ITextElement).Symbol.Font.Size *
                    (decimal)(pAnnoFclsExtSur.ReferenceScale / pAnnoFclsExtTag.ReferenceScale);
                }                
                pTextSymbol.Font = pFontDisp;
                pTxtElement.Symbol = pTextSymbol;


                pElement.Geometry = pAnnoFeatSource.Annotation.Geometry;//.Envelope.LowerLeft;// mFeature.Shape.Envelope.LowerLeft;

                pAnnoFeatTarget.Annotation = pTxtElement as IElement;

            }
            catch (Exception e)
            {
                LogHelper.WriteLog("注记[" + (pAnnoFeatSource as IRow).OID + "]转换失败！" + e.Message, zjgisLogType.zjgisLogError);
                return false;
            }

            return true;
        }

        #endregion
    }
}